home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BBS in a Box 7
/
BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso
/
Files
/
Art
/
P
/
PhotoShopDev.cpt
/
PhotoShopDev
/
Fil-Think C 4.0
/
Dissolve.c
next >
Wrap
Text File
|
1990-02-13
|
8KB
|
427 lines
/*
File: Dissolve.c
Copyright 1990 by Thomas Knoll.
Think C source file for Dissolve example.
*/
#include <MacTypes.h>
#include <MemoryMgr.h>
#include <ResourceMgr.h>
#include <Quickdraw.h>
#include <Color.h>
#include <DialogMgr.h>
#include <OSUtil.h>
#include <PackageMgr.h>
#include <SysErr.h>
#include <ToolboxUtil.h>
#include <pascal.h>
#include <SetUpA4.h>
#include "FilterInterface.h"
#define nil 0L
#define Length(string) (*(unsigned char *)(string))
typedef struct TParameters
{
short percent;
} TParameters, *PParameters, **HParameters;
short gResult;
FilterRecordPtr gStuff;
/*****************************************************************************/
/* Calls the host's TestAbort function */
Boolean TestAbort (void)
{
return CallPascalB (gStuff->abortProc);
}
/*****************************************************************************/
/* Calls the host's UpdateProgress procedure */
void UpdateProgress (done, total)
long done;
long total;
{
CallPascal (done, total, gStuff->progressProc);
}
/*****************************************************************************/
/* Centers a dialog template 1/3 of the way down on the main screen. */
void CenterDialog (dt)
DialogTHndl dt;
#define menuHeight 20
{
Rect r;
short width;
short height;
width = screenBits.bounds.right;
height = screenBits.bounds.bottom;
r = (**dt).boundsRect;
OffsetRect (&r, -r.left, -r.top);
OffsetRect (&r, (width - r.right) / 2,
(height - r.bottom - menuHeight) / 3 + menuHeight);
(**dt).boundsRect = r;
}
#undef menuHeight
/*****************************************************************************/
/* Displays the about dialog box for the plug-in module. */
void DoAbout (void)
#define dialogID 16000
{
short item;
DialogPtr dp;
DialogTHndl dt;
dt = (DialogTHndl) GetResource ('DLOG', dialogID);
HNoPurge ((Handle) dt);
CenterDialog (dt);
dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
ModalDialog (nil, &item);
DisposDialog (dp);
HPurge ((Handle) dt);
}
#undef dialogID
/*****************************************************************************/
/* UserItem to outline the OK button in a dialog box. */
pascal void OutlineOK (dp, item)
DialogPtr dp;
short item;
{
Rect r;
Handle h;
short itemType;
SetUpA4 ();
item = OK;
GetDItem (dp, item, &itemType, &h, &r);
PenNormal ();
PenSize (3, 3);
InsetRect (&r, -4, -4);
FrameRoundRect (&r, 16, 16);
PenNormal ();
RestoreA4 ();
}
/*****************************************************************************/
/* Asks the user for the plug-in filter module's parameters. Note that
the image size information is not yet defined at this point. Also, do
not assume that the calling program will call this routine every time the
filter is run (it may save the data held by the parameters handle in
a macro file). */
void DoParameters (void)
#define dialogID 16001
#define hookItem 3
#define percentItem 4
{
Rect r;
long x;
short j;
Str255 s;
Handle h;
short item;
DialogPtr dp;
short itemType;
DialogTHndl dt;
Handle percentText;
if (!gStuff->parameters)
{
gStuff->parameters = NewHandle (sizeof (TParameters));
if (!gStuff->parameters)
{
gResult = memFullErr;
return;
}
((PParameters) *gStuff->parameters)->percent = 50;
}
dt = (DialogTHndl) GetResource ('DLOG', dialogID);
HNoPurge ((Handle) dt);
CenterDialog (dt);
dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
RememberA4 ();
GetDItem (dp, hookItem, &itemType, &h , &r);
SetDItem (dp, hookItem, itemType, (Handle) &OutlineOK, &r);
GetDItem (dp, percentItem, &itemType, &percentText, &r);
NumToString (((PParameters) *gStuff->parameters)->percent, s);
SetIText (percentText, s);
do
{
SelIText (dp, percentItem, 0, 32767);
ModalDialog (nil, &item);
if (item == OK)
{
GetIText (percentText, s);
StringToNum (s, &x);
if (x < 1 || x > 99)
item = 0;
for (j = 1; j <= Length (s); j++)
if (s[j] < '0' || s[j] > '9')
item = 0;
if (item == 0)
SysBeep (1);
}
}
while (item != OK && item != Cancel);
DisposDialog (dp);
HPurge ((Handle) dt);
if (item == Cancel)
{
gResult = 1;
return;
}
((PParameters) *gStuff->parameters)->percent = x;
}
#undef dialogID
#undef hookItem
#undef percentItem
/*****************************************************************************/
/* Prepare to filter an image. If the plug-in filter needs a large amount
of buffer memory, this routine should set the bufferSpace field to the
number of bytes required. */
void DoPrepare (void)
{
}
/*****************************************************************************/
/* Requests pointer to the first part of the image to be filtered. */
void DoStart (void)
{
gStuff->inRect = gStuff->filterRect;
gStuff->inRect.bottom = gStuff->inRect.top + 1;
gStuff->inLoPlane = 0;
gStuff->inHiPlane = gStuff->planes - 1;
gStuff->outRect = gStuff->inRect;
gStuff->outLoPlane = 0;
gStuff->outHiPlane = gStuff->planes - 1;
}
/*****************************************************************************/
/* Filters the area and requests the next area. */
void DoContinue (void)
{
short rand;
short count;
short plane;
short percent;
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char *srcPtr;
unsigned char *dstPtr;
if (TestAbort ())
{
gResult = 1;
return;
}
UpdateProgress ((long) gStuff->inRect.top - gStuff->filterRect.top,
(long) gStuff->filterRect.bottom - gStuff->filterRect.top);
percent = ((PParameters) *gStuff->parameters)->percent;
r = gStuff->background.red >> 8;
g = gStuff->background.green >> 8;
b = gStuff->background.blue >> 8;
srcPtr = (unsigned char *) gStuff->inData;
dstPtr = (unsigned char *) gStuff->outData;
count = gStuff->filterRect.right - gStuff->filterRect.left;
while (count--)
{
rand = Random ();
rand = (rand < 0 ? -rand : rand);
if (rand % 100 < percent)
if (gStuff->planes == 3)
{
*(dstPtr++) = r;
*(dstPtr++) = g;
*(dstPtr++) = b;
srcPtr += 3;
}
else
{
*(dstPtr++) = r;
srcPtr++;
}
else
for (plane = 0; plane < gStuff->planes; plane++)
*(dstPtr++) = *(srcPtr++);
}
gStuff->inRect.top = gStuff->inRect.top + 1;
gStuff->inRect.bottom = gStuff->inRect.bottom + 1;
if (gStuff->inRect.top >= gStuff->filterRect.bottom)
SetRect (&gStuff->inRect, 0, 0, 0, 0);
gStuff->outRect = gStuff->inRect;
}
/*****************************************************************************/
/* This routine will always be called if DoStart does not return an error
(even if DoContinue returns an error or the user aborts the operation).
This allows the module to perform any needed cleanup. None is required
in this example. */
void DoFinish (void)
{
}
/*****************************************************************************/
/* Main dispatching routine. Initializes and sets up the global variables,
and performs the operation specified by the selector. */
pascal void main (selector, stuff, data, result)
short selector;
FilterRecordPtr stuff;
long *data;
short *result;
{
/* Allow access to global variables */
RememberA0 ();
SetUpA4 ();
/* Copy the current quickdraw globals into the plug-in local copy */
asm
{
MOVE.L (A5),A0 ; Get address of real quickdraw globals
SUB.L #126,A0 ; Move to start
LEA randSeed,A1 ; Get address of local copy
MOVE.W #64,D0 ; Globals are 65 words long
@1 MOVE.W (A0)+,(A1)+ ; Copy a word
DBF D0,@1 ; Move to next word
}
/* Perform the requested operation */
gStuff = stuff;
gResult = noErr;
switch (selector)
{
case filterSelectorAbout:
DoAbout ();
break;
case filterSelectorParameters:
DoParameters ();
break;
case filterSelectorPrepare:
DoPrepare ();
break;
case filterSelectorStart:
DoStart ();
break;
case filterSelectorContinue:
DoContinue ();
break;
case filterSelectorFinish:
DoFinish ();
break;
default:
gResult = filterBadParameters;
}
*result = gResult;
/* Restore the application's A4 register */
RestoreA4 ();
}